﻿#include "Autosave.h"
#include <QObject>
#include <QSettings>
#include <QMetaProperty>
#include <QDebug>
#include <QLoggingCategory>

Q_LOGGING_CATEGORY(autosave, "Autosave.log")

Autosave::Autosave(QObject *obj):m_obj(obj)
{

}

Autosave::~Autosave()
{
    QSettings settings(QString("%1.ini").arg(m_obj->metaObject()->className()),QSettings::IniFormat);
    serialization(m_obj,&settings);
}

void Autosave::initialize()
{
    QSettings settings(QString("%1.ini").arg(m_obj->metaObject()->className()),QSettings::IniFormat);
    deserialization(m_obj,&settings);
}

void Autosave::serialization(QObject *obj,QSettings *settings,QString parentName)
{
    QString className = obj->metaObject()->className();
    QString prefix = parentName.isEmpty() ? className : parentName + "/" + className;

    auto meta = obj->metaObject();
    auto count = meta->propertyCount();
    settings->setValue(QString("obj/%1/count").arg(prefix),count);

    for(auto i = 0;i < count;++i){
        auto &&pro = meta->property(i);
        qCDebug(autosave) << pro.name() << pro.type() << pro.read(obj);
        if(pro.type() >= QVariant::UserType){
            auto sub_obj = pro.read(obj).value<QObject*>();
            if(sub_obj){
                serialization(sub_obj,settings,className);
            }
        }else{
            if(parentName.isEmpty()){
                settings->setValue(prefix + "/" + pro.name(),pro.read(obj));
            }else{
                settings->setValue(prefix + "/" + pro.name(),pro.read(obj));
            }
        }
    }
}

void Autosave::deserialization(QObject *obj,QSettings *settings,QString parentName)
{
    QString className = obj->metaObject()->className();
    QString prefix = parentName.isEmpty() ? className : parentName + "/" + className;

    auto meta = obj->metaObject();
    auto count = settings->value(QString("obj/%1/count").arg(prefix),0).toInt();

    for(auto i = 0;i < count;++i){
        auto &&pro = meta->property(i);
        qCDebug(autosave) << pro.name() << pro.type() << pro.read(obj);
        if(pro.type() >= QVariant::UserType){
            auto sub_obj = pro.read(obj).value<QObject*>();
            if(sub_obj){
                deserialization(sub_obj,settings,className);
            }
        }else{
            if(parentName.isEmpty()){
                pro.write(obj,settings->value(prefix + "/" + pro.name()));
            }else{
                pro.write(obj,settings->value(prefix + "/" + pro.name()));
            }
        }
    }
}
